﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GLinq
{
    class Program
    {
        static IEnumerable<ElementIndex2D> GetBBoxTiles(BBox box, int blockSize)
        {
            for (int i = (box.X + 64) / 128; i <= (box.X + box.W + 64) / 128; i++)
                for (int j = (box.Y + 64) / 128; j <= (box.Y + box.H + 64) / 128; j++)
                    yield return new ElementIndex2D(i, j);
        }

        static void Rasterizer(Buffer<Triangle> geometry, int width, int height)
        {
            var gqueue = geometry.ToConsumableQueue();
            int smCount = 24;
            var bins = Grid<int>.Create(new GridSize(smCount)).SelectParallel(cell=>
                            gqueue.Consume(512, geoms=>
                                geoms.Scatter((tri) => GetBBoxTiles(tri.Content.AABB, 128))));
            var cbins = bins.SelectParallel(bin=>bin.Content.SelectParallel(t=>t.Content.ToConsumableQueue()));

            int binWidth = (width/128);
            int binHeight = (height/128);
            var binTasks = new TaskSet(binWidth*binHeight);
            
            binTasks.ParallelConstruct(id=>bins.Sum(bin=>(bin[id%binWidth,id/binWidth].Count+511)/512));

            var tiles = Grid<int>.Create(new GridSize(smCount)).SelectParallel(cell=>
                binTasks.Peek(binId=>
                    ConsumptionPool.Aggregate(512, 
                        remaining => cbins.Min(bin=> bin[binId%binWidth,binId/binWidth].First().Id)
                                              [binId%binWidth,binId/binWidth]
                                              .ConsumeOnce(remaining))
                    .Scatter(tri=>tri.Content.GetOverlappingTiles(8))
                )).Union();

           
        }

        static void Main(string[] args)
        {
        }
    }

    struct BBox
    {
        public int X, Y, W, H;
        public BBox(int x, int y, int w, int h)
        {
            X = x;
            Y = y;
            W = w;
            H = h;
        }
    }

    class Triangle
    {
        internal int Id = 0;
        internal BBox AABB;
        internal bool Overlaps(int x, int y, int w, int h)
        {
            throw new NotImplementedException();
        }
        internal IEnumerable<ElementIndex2D> GetOverlappingTiles(int tileSize)
        {
            throw new NotImplementedException();
        }
    }
}
